sorter.js ➔ getTableBody   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
nc 1
dl 0
loc 1
rs 10
c 1
b 0
f 0
nop 0
1
var addSorting = (function () {
2
    "use strict";
3
    var cols,
4
        currentSort = {
5
            index: 0,
6
            desc: false
7
        };
8
9
    // returns the summary table element
10
    function getTable() { return document.querySelector('.coverage-summary'); }
11
    // returns the thead element of the summary table
12
    function getTableHeader() { return getTable().querySelector('thead tr'); }
13
    // returns the tbody element of the summary table
14
    function getTableBody() { return getTable().querySelector('tbody'); }
15
    // returns the th element for nth column
16
    function getNthColumn(n) { return getTableHeader().querySelectorAll('th')[n]; }
17
18
    // loads all columns
19
    function loadColumns() {
20
        var colNodes = getTableHeader().querySelectorAll('th'),
21
            colNode,
22
            cols = [],
23
            col,
24
            i;
25
26
        for (i = 0; i < colNodes.length; i += 1) {
27
            colNode = colNodes[i];
28
            col = {
29
                key: colNode.getAttribute('data-col'),
30
                sortable: !colNode.getAttribute('data-nosort'),
31
                type: colNode.getAttribute('data-type') || 'string'
32
            };
33
            cols.push(col);
34
            if (col.sortable) {
35
                col.defaultDescSort = col.type === 'number';
36
                colNode.innerHTML = colNode.innerHTML + '<span class="sorter"></span>';
37
            }
38
        }
39
        return cols;
40
    }
41
    // attaches a data attribute to every tr element with an object
42
    // of data values keyed by column name
43
    function loadRowData(tableRow) {
44
        var tableCols = tableRow.querySelectorAll('td'),
45
            colNode,
46
            col,
47
            data = {},
48
            i,
49
            val;
50
        for (i = 0; i < tableCols.length; i += 1) {
51
            colNode = tableCols[i];
52
            col = cols[i];
53
            val = colNode.getAttribute('data-value');
54
            if (col.type === 'number') {
55
                val = Number(val);
56
            }
57
            data[col.key] = val;
58
        }
59
        return data;
60
    }
61
    // loads all row data
62
    function loadData() {
63
        var rows = getTableBody().querySelectorAll('tr'),
64
            i;
65
66
        for (i = 0; i < rows.length; i += 1) {
67
            rows[i].data = loadRowData(rows[i]);
68
        }
69
    }
70
    // sorts the table using the data for the ith column
71
    function sortByIndex(index, desc) {
72
        var key = cols[index].key,
73
            sorter = function (a, b) {
74
                a = a.data[key];
75
                b = b.data[key];
76
                return a < b ? -1 : a > b ? 1 : 0;
77
            },
78
            finalSorter = sorter,
79
            tableBody = document.querySelector('.coverage-summary tbody'),
80
            rowNodes = tableBody.querySelectorAll('tr'),
81
            rows = [],
82
            i;
83
84
        if (desc) {
85
            finalSorter = function (a, b) {
86
                return -1 * sorter(a, b);
87
            };
88
        }
89
90
        for (i = 0; i < rowNodes.length; i += 1) {
91
            rows.push(rowNodes[i]);
92
            tableBody.removeChild(rowNodes[i]);
93
        }
94
95
        rows.sort(finalSorter);
96
97
        for (i = 0; i < rows.length; i += 1) {
98
            tableBody.appendChild(rows[i]);
99
        }
100
    }
101
    // removes sort indicators for current column being sorted
102
    function removeSortIndicators() {
103
        var col = getNthColumn(currentSort.index),
104
            cls = col.className;
105
106
        cls = cls.replace(/ sorted$/, '').replace(/ sorted-desc$/, '');
107
        col.className = cls;
108
    }
109
    // adds sort indicators for current column being sorted
110
    function addSortIndicators() {
111
        getNthColumn(currentSort.index).className += currentSort.desc ? ' sorted-desc' : ' sorted';
112
    }
113
    // adds event listeners for all sorter widgets
114
    function enableUI() {
115
        var i,
116
            el,
117
            ithSorter = function ithSorter(i) {
0 ignored issues
show
Comprehensibility Naming Best Practice introduced by
The variable ithSorter already seems to be declared on line 117. Consider using another variable name or omitting the var keyword.

This check looks for variables that are declared in multiple lines. There may be several reasons for this.

In the simplest case the variable name was reused by mistake. This may lead to very hard to locate bugs.

If you want to reuse a variable for another purpose, consider declaring it at or near the top of your function and just assigning to it subsequently so it is always declared.

Loading history...
118
                var col = cols[i];
119
120
                return function () {
121
                    var desc = col.defaultDescSort;
122
123
                    if (currentSort.index === i) {
124
                        desc = !currentSort.desc;
125
                    }
126
                    sortByIndex(i, desc);
127
                    removeSortIndicators();
128
                    currentSort.index = i;
129
                    currentSort.desc = desc;
130
                    addSortIndicators();
131
                };
132
            };
133
        for (i =0 ; i < cols.length; i += 1) {
134
            if (cols[i].sortable) {
135
                // add the click event handler on the th so users
136
                // dont have to click on those tiny arrows
137
                el = getNthColumn(i).querySelector('.sorter').parentElement;
138
                if (el.addEventListener) {
139
                    el.addEventListener('click', ithSorter(i));
140
                } else {
141
                    el.attachEvent('onclick', ithSorter(i));
142
                }
143
            }
144
        }
145
    }
146
    // adds sorting functionality to the UI
147
    return function () {
148
        if (!getTable()) {
149
            return;
150
        }
151
        cols = loadColumns();
152
        loadData(cols);
0 ignored issues
show
Bug introduced by
The call to loadData seems to have too many arguments starting with cols.
Loading history...
153
        addSortIndicators();
154
        enableUI();
155
    };
156
})();
157
158
window.addEventListener('load', addSorting);
159